<?php

namespace app\console\command;

use app\common\model\Vod;
use CloudFlare\CloudFlareApiClient;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Log;

class UploadCloudflareVod extends Command
{
    protected function configure()
    {
        $this->setName('upload_cloudflare_vod')
            ->setDescription('upload video files to cloudflare vod');
    }

    protected function execute(Input $input, Output $output)
    {
        $output->info("execute upload cloudflare");
        try {
            $videoList = Db::name('video')->whereNotIn('id', function ($query) {
                $query->name('vod')->where('status', 'in', [Vod::VOD_STATUS_PUBLISHED, Vod::VOD_STATUS_UPLOADED])->where('platform', '=', 'cloudflare')->field('video_id');
            })
//                ->where('id', '>', 104)
                ->where('status', '=', 'normal')
//                ->limit(0, 1)
                ->select();
            foreach ($videoList as $video) {
                try {
                    Log::info('begin to upload video:' . $video['id']);
                    if ($this->isStorageFull()) {
                        Log::info('storage is full');
                        break;
                    }
                    $videolist = Db::name('videolist')->where('id', $video['pid'])->find();
                    if ($videolist['status'] != 'normal') {
                        continue;   // skip video list that is not normal
                    }
                    $this->uploadVideo($video['id']);
                    sleep(1);
                } catch (\Exception $exception) {
                    Log::error($exception->getMessage());
                    Log::error($exception->getTraceAsString());
                }
            }
        } catch (\Exception $exception) {
            Log::error($exception->getMessage());
            Log::error($exception->getTraceAsString());
//            $output->error($exception->getMessage());
        }
    }

    protected function uploadVideo($videoId)
    {
        $video = Db::name('video')->where(['id' => $videoId])->find();
        $videoList = Db::name('videolist')->where('id', $video['pid'])->find();
        $video['videourl'] = fullMediaUrl($video['videourl']);
        $title = $videoList['name'] . '-' . $video['name'];
        $cfClient = new CloudFlareApiClient();
        $result = $cfClient->postUploadVideo($video['videourl'], $title);
        if ($result) {
            if (is_string($result)) {
                $result = json_decode($result, true);
            }
            Log::info('result:' . json_encode($result));
            if ($result['success'] == false) {
                Log::error('upload video failed');
                return;
            }
            $status = Vod::VOD_STATUS_NO_UPLOAD;
            if ($result['result']['status'] == 'ready') {
                $status = Vod::VOD_STATUS_UPLOADED;
            }
            Vod::addVodViaCloudFlare($videoId, $videoList['id'], $title, 'M3U8', $result['result']['uid'], $result['result']['playback']['hls'], $status);
        }
    }

    protected function uploadLocalVideo($videoId)
    {
        $video = Db::name('video')->where(['id' => $videoId])->find();
        $videoList = Db::name('videolist')->where('id', $video['pid'])->find();
        $videoLocalPath = 'g:/utils/storage/rmshort';
        $video['videourl'] = $videoLocalPath . $video['videourl'];
        if (!file_exists($video['videourl'])) {
            Log::error('file not exists:' . $video['videourl']);
            return;
        }
        $title = $videoList['name'] . '-' . $video['name'];
        $cfClient = new CloudFlareApiClient();
        $result = $cfClient->postDirectUpload($title);
        if ($result) {
            if (is_string($result)) {
                $result = json_decode($result, true);
            }
            Log::info('result:' . json_encode($result));
            if ($result['success'] == false) {
                Log::error('upload local video postDirectUpload failed');
                return;
            }
            $status = Vod::VOD_STATUS_NO_UPLOAD;
            Vod::addVodViaCloudFlare($videoId, $videoList['id'], $title, 'M3U8', $result['result']['uid'], '', $status);
            $result = $cfClient->postDirectUploadVideo($result['result']['uploadURL'], $video['videourl'], $title);
            Log::info('postDirectUploadVideo result:' . json_encode($result));
        }
    }

    protected function isStorageFull()
    {
        $cfClient = new CloudFlareApiClient();
        $result = $cfClient->getStorageUseage();
        if ($result) {
            if (is_string($result)) {
                $result = json_decode($result, true);
            }
            Log::info('storage result:' . json_encode($result));
            if ($result['success'] == false) {
                Log::error('get storage failed');
                return false;
            }
            if ($result['result']['totalStorageMinutes'] >= ($result['result']['totalStorageMinutesLimit'] - 10)) {
                return true;
            }
        }
        return false;

    }
}
